<?php
// +----------------------------------------------------------------------
// | Copyright © Sogu Technologies Co. Ltd 2018-2050 All rights reserved.
// +----------------------------------------------------------------------
// | File name: BindingCardController.php
// +----------------------------------------------------------------------
// | Author: liuju
// +----------------------------------------------------------------------
// | Description: 用于处理绑定、解绑、换绑银行卡
// +----------------------------------------------------------------------
// | Others: 其他内容的说明
// +----------------------------------------------------------------------
// | History: 修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简述
// +----------------------------------------------------------------------
// | 1.Date: 2019-01-02 Author: liuju Modification: 创建
// +----------------------------------------------------------------------

namespace App\Http\Controllers\Frontend\V10\BankCard;


use App\Constants\RedisKey;
use App\Facades\CommonPlatformRequestFacade;
use App\Facades\MoneyPlatformRequestFacade;
use App\Http\Controllers\Controller;
use App\Http\Requests\Frontend\V10\BankCard\BindCardRequest;
use App\Http\Requests\Frontend\V10\BankCard\ChangeCardRequest;
use App\Http\Requests\Frontend\V10\BankCard\VerifyRequest;
use App\Models\AdminBankIcon;
use App\Models\BankCode;
use App\Models\LoanApply;
use App\Models\User;
use App\Models\UserBankCard;
use App\Models\UserBindCardException;
use App\Models\UserChangeBankCardRecord;
use App\Models\UserGlobal;
use App\Models\UserInfo;
use App\Models\UserLoanRequest;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\Response;

class BindCardController extends Controller
{

    protected $user;

    public function __construct()
    {
        $this->user = auth('api')->user();
        $this->middleware('auth:api');
    }


    /**
     * Description: 用户申请绑卡获取短信验证码&&订单号
     * Author: liuju
     * DateTime: 2019-01-02 16:32
     * @param VerifyRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function applyBindCard(Request $request)
    {
        // 银行卡
        $cardNum = $request->get('bank_card_num');
        //手机号
        $phoneNum = $request->get('phone_num');
        //持卡人姓名
        $realName = $request->get('real_name');
        // 需不需要校验
        $isVerify = $request->get('isVerify');
        if($isVerify){
            return $this->applyBindCardVerify($cardNum, $phoneNum, $realName);
        }else{
            return $this->applyBindCardNoVerify($cardNum, $phoneNum, $realName);
        }
    }

    /**
     * Description: 用户申请绑卡  不验证
     * Author: cg
     * DateTime: 2019-3-27 17:32
     */
    public function applyBindCardNoVerify($cardNum, $phoneNum, $realName)
    {
        Log::debug('用户申请绑卡:银行卡->'.$cardNum.'->手机号->'.$phoneNum.'->持卡人姓名->'.$realName);
        $valid = $this->user->valid;
        if (!$valid || !$valid->num) {
            return failed('请您先进行实名认证');
        }
        $certNum = $valid->num;
        //获取绑定银行卡的短信验证码和请求编号
        $res = CommonPlatformRequestFacade::applyBindCard($cardNum, $certNum, $phoneNum, $realName);
        Log::debug('获取银行卡短信验证码和请求编号:'.json_encode($res,JSON_UNESCAPED_UNICODE).'->phoneNum'.$phoneNum);
        if ($res['code'] === '01') {
            Log::debug('请求编号->'.$res['data']['orderNo']);
            // 记录该用户申请绑卡的卡号，用于确认申请校验
            $lastLoanId = UserLoanRequest::where('user_id', $this->user->id)->where('current', 1)->value('id');
            $bank_apply_key = sprintf(RedisKey::BANK_CARD_APPLY, $lastLoanId);
            if(Redis::exists($bank_apply_key)) {
                Redis::del($bank_apply_key);
            }
            Redis::set($bank_apply_key, $cardNum);

            return respond([
                'order_num' => $res['data']['orderNo'],
            ], '请求成功，请输入验证码');
        } else {
            return respond([], '' . $res['message'], Response::HTTP_BAD_REQUEST);
        }
    }

    /**
     * Description: 用户申请绑卡获取短信验证码&&订单号 验证
     * Author: cg
     * DateTime: 2019-3-27 17:32
     * @return \Illuminate\Http\JsonResponse
     */
    public function applyBindCardVerify($cardNum, $phoneNum, $realName){
        Log::debug('用户申请绑卡:银行卡->'.$cardNum.'->手机号->'.$phoneNum.'->持卡人姓名->'.$realName);
        $valid = $this->user->valid;
        if (!$valid || !$valid->num) {
            return failed('请您先进行实名认证');
        }
        $certNum = $valid->num;


//        获取银行卡相关信息，银行卡名称、银行卡全称、银行卡编码，是否是信用卡
        $codeRes = CommonPlatformRequestFacade::bankCode($cardNum);
        Log::debug('获取银行卡相关信息:'.json_encode($codeRes,JSON_UNESCAPED_UNICODE).'->phoneNum'.$phoneNum);
        if ($codeRes['code'] !== '01') {
            return failed('请求异常' . $codeRes['message']);
        }

        //获取绑定银行卡的短信验证码和请求编号
        $res = CommonPlatformRequestFacade::applyBindCard($cardNum, $certNum, $phoneNum, $realName);
        Log::debug('获取银行卡短信验证码和请求编号:'.json_encode($res,JSON_UNESCAPED_UNICODE).'->phoneNum'.$phoneNum);
        if ($res['code'] === '01') {
            Log::debug('请求编号->'.$res['data']['orderNo']);
            return respond([
                'order_num' => $res['data']['orderNo'],
            ], '请求成功，请输入验证码');
        } else {
            return respond([], '' . $res['message'], Response::HTTP_BAD_REQUEST);
        }
    }

    /**
     * Description: 获取银行编码和是否是信用卡
     * Author: cg
     * DateTime: 2019-3-27 17:32
     * @param Request $request
     * @return mixed
     */
    public function queryBankCode(Request $request)
    {
        $bankCardId = $request->get('bankCardId', '');
        if(!$bankCardId){
            return failed('缺少必要参数');
        }
        $codeRes = CommonPlatformRequestFacade::bankCode($bankCardId);
        Log::debug('获取银行编码和是否是信用卡:'.json_encode($codeRes,JSON_UNESCAPED_UNICODE).'->bankCardId'.$bankCardId);
        try{
            $data = $codeRes['data'];
            $bankIcon = AdminBankIcon::where('bank_name', $data['bank_name'])->first();
            if(!empty($bankIcon)){
                $data['bank_icon'] =  $bankIcon->icon_oss_url ? Storage::disk('oss')->signUrl($bankIcon->icon_oss_url,3600):'';
            }else{
                $bankIcon = AdminBankIcon::where('bank_name', '其他')->first();
                $data['bank_icon'] = $bankIcon->icon_oss_url ? Storage::disk('oss')->signUrl($bankIcon->icon_oss_url,3600):'';
            }
        }catch (\Exception $exception){
            $data = [];
        }
        return success($data);
    }




    /**
     * Description:绑卡确认接口
     * Author: liuju
     * DateTime: 2019-01-15 20:22
     * @param BindCardRequest $request
     * @return mixed
     * @throws \App\Exceptions\GeneralException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function bindCardConfirm(Request $request)
    {
        //银行卡号码
        $cardNum = $request->get('bank_card_num');
        //银行卡预留手机号码
        $phoneNum = $request->get('phone_num');
        //持卡人姓名
        $realName = $request->get('real_name');
        //短信验证码
        $smsCode = $request->get('sms_code');
        //请求编号
        $orderNum = $request->get('order_num');
        //银行卡类型
        $isCredit = $request->get('is_credit');
        // 需不需要校验
        $isVerify = $request->get('isVerify');
        $bank_name = $request->get('bank_name');
        $bank_name_show = $request->get('bank_name_show');
        $bank_code = $request->get('bank_code');
        if($isVerify){
            return $this->bindCardConfirmVerify($cardNum, $phoneNum, $realName, $smsCode, $orderNum, $isCredit);
        }else{
            return $this->bindCardConfirmNoVerify($cardNum, $phoneNum, $realName, $smsCode, $orderNum, $isCredit, $bank_name, $bank_name_show, $bank_code);
        }
    }

    /**
     * Description: 进件绑卡不需要验证
     * Author: cg
     * DateTime: 2019-03-28 16:27
     * @param $cardNum
     * @param $phoneNum
     * @param $realName
     * @param $smsCode
     * @param $orderNum
     * @param $isCredit
     * @param $bank_name
     * @param $bank_name_show
     * @param $bank_code
     * @return mixed
     */
    public function bindCardConfirmNoVerify($cardNum, $phoneNum, $realName, $smsCode, $orderNum, $isCredit, $bank_name, $bank_name_show, $bank_code)
    {
        Log::debug('绑卡确认:银行卡号码->'.$cardNum.'->银行卡预留手机号码->'.$phoneNum.'->持卡人姓名->'.
            $realName.'->短信验证码->'.$smsCode.'->请求编号->'.$orderNum.'->银行卡类型->'.$isCredit.'银行名称->'
            .$bank_name.'简称->'.$bank_name_show.'编号->'.$bank_code);

        $valid = $this->user->valid;
        if (!$valid || !$valid->num) {
            return failed('请您先进行实名认证');
        }
        $certNum = $valid->num;

        // 判断申请绑卡和确认绑卡是否是同一个号码
        $lastLoanId = UserLoanRequest::where('user_id', $this->user->id)->where('current', 1)->value('id');
        $bank_apply_key = sprintf(RedisKey::BANK_CARD_APPLY, $lastLoanId);
        $apply_card = Redis::get($bank_apply_key);
        if($apply_card !== $cardNum){
            return failed('申请绑卡的卡号和确认绑卡的卡号不一致');
        }
        Redis::del($bank_apply_key);
        //记录用户银行卡信息
        $bankCard = new UserBankCard();
        $bankCard->uid = $this->user->id;
        $bankCard->card_username = $realName;
        $bankCard->phone_num = $phoneNum;
        $bankCard->card_num = $cardNum;

        //绑定银行卡操作
        $resBindCard = CommonPlatformRequestFacade::bindCardConfirm($cardNum, $certNum, $smsCode, $orderNum, $phoneNum, $realName);
        Log::debug('绑定结果' . json_encode($resBindCard,JSON_UNESCAPED_UNICODE).'->phoneNum'.$phoneNum);
        if ($resBindCard['code'] !== '01') {
            return respond([], '请求失败，' . $resBindCard['message'], Response::HTTP_BAD_REQUEST);
        }
        $bankCard->hold_agreement_num = !empty($resBindCard['data']['agreementNoEncase']) ? $resBindCard['data']['agreementNoEncase'] : '';
        $bankCard->order_num = !empty($resBindCard['data']['orderNo']) ? $resBindCard['data']['orderNo'] : '';

        $bankCard->bank_name_show = $bank_name_show ?? '';
        $bankCard->bank_name = $bank_name ?? $bank_name_show;
        if(!$bank_code){
            if($bank_name_show == '其他'){
                $bank_code = '0';
            }else{
                $admin_bank = BankCode::where('bank_name_show', $bank_name_show)->first();
                if(!$admin_bank){
                    $bank_code = '0';
                }else{
                    $bank_code = $admin_bank->bank_code;
                }
            }
        }
        $bankCard->bank_code = $bank_code;
        $bankCard->is_credit = UserBankCard::isCredit($isCredit);

        if($bankCard->bank_name_show == '' || $bankCard->bank_name_show == null){
            $bankCard->bank_name_show = "";
        }
        if($bankCard->bank_name == '' || $bankCard->bank_name == null){
            $bankCard->bank_name = "";
        }
        $bankCard->save();
        return respond([
            'card_id' => $bankCard->id,
        ], '绑定成功');
    }

    /**
     * Description: 个人中心绑卡需要验证
     * Author: cg
     * DateTime: 2019-03-28 16:27
     * @param $cardNum
     * @param $phoneNum
     * @param $realName
     * @param $smsCode
     * @param $orderNum
     * @param $isCredit
     * @return mixed
     */
    public function bindCardConfirmVerify($cardNum, $phoneNum, $realName, $smsCode, $orderNum, $isCredit)
    {
        Log::debug('绑卡确认:银行卡号码->'.$cardNum.'->银行卡预留手机号码->'.$phoneNum.'->持卡人姓名->'.$realName.'->短信验证码->'.$smsCode.'->请求编号->'.$orderNum.'->银行卡类型->'.$isCredit);
        $valid = $this->user->valid;
        if (!$valid || !$valid->num) {
            return failed('请您先进行实名认证');
        }
        $certNum = $valid->num;

        //获取银行卡相关信息，银行卡名称、银行卡全称、银行卡编码，是否是信用卡
        $codeRes = CommonPlatformRequestFacade::bankCode($cardNum);
        Log::debug('获取银行卡相关信息:'.json_encode($codeRes,JSON_UNESCAPED_UNICODE).'->phoneNum'.$phoneNum);
        if ($codeRes['code'] !== '01') {
            return respond([], '请求失败，' . $codeRes['message'], Response::HTTP_BAD_REQUEST);
        }
        if ($isCredit && $codeRes['data']['is_credit'] != $isCredit) {
            return respond([], '请求失败，该卡号不满足您的绑卡需求', Response::HTTP_BAD_REQUEST);
        }

        //验证银行卡是否可以签约
        $checkCardCanBind = UserBankCard::where('card_num', $cardNum)->valid()->first();
        //用户绑定过该银行，验证协议号是否有效
        if ($checkCardCanBind && $checkCardCanBind->hold_agreement_num) {
            $checkHoldAgreement = CommonPlatformRequestFacade::checkHoldAgreement($checkCardCanBind->hold_agreement_num);
            Log::debug('验证协议号:'.json_encode($checkHoldAgreement,JSON_UNESCAPED_UNICODE).'->phoneNum'.$phoneNum);
            if ($checkHoldAgreement && $checkHoldAgreement['code'] === '01') {
                return failed('请求失败，' . $checkHoldAgreement['message']);
            } else {
                $checkCardCanBind->update(['is_valid'=>UserBankCard::VALID_NO]);
            }
        }

        //记录用户银行卡信息
        $bankCard = new UserBankCard();
        $bankCard->uid = $this->user->id;
        $bankCard->card_username = $realName;
        $bankCard->phone_num = $phoneNum;
        $bankCard->card_num = $cardNum;

        //判定是否在还款中  就是 需要需要换体现的银行卡

        //绑定银行卡操作

        $resBindCard = CommonPlatformRequestFacade::bindCardConfirm($cardNum, $certNum, $smsCode, $orderNum, $phoneNum, $realName);
        Log::debug('绑定结果' . json_encode($resBindCard,JSON_UNESCAPED_UNICODE).'->phoneNum'.$phoneNum);
        if ($resBindCard['code'] !== '01') {
            return respond([], '请求失败，' . $resBindCard['message'], Response::HTTP_BAD_REQUEST);
        }
        $bankCard->hold_agreement_num = !empty($resBindCard['data']['agreementNoEncase']) ? $resBindCard['data']['agreementNoEncase'] : '';
        $bankCard->order_num = !empty($resBindCard['data']['orderNo']) ? $resBindCard['data']['orderNo'] : '';
        $bankCard->bank_name = !empty($codeRes['data']['bank_name']) ? $codeRes['data']['bank_name'] : '';
        $bankCard->bank_name_show = !empty($codeRes['data']['bank_name_show']) ? $codeRes['data']['bank_name_show'] : '';
        $bankCard->bank_code = !empty($codeRes['data']['code']) ? $codeRes['data']['code'] : '';
        $bankCard->is_credit = UserBankCard::isCredit($codeRes['data']['is_credit']);
        $bankCard->save();
        return respond([
            'card_id' => $bankCard->id,
        ], '绑定成功');
    }


    /**
     * Description: 用户换卡操作
     * Author: liuju
     * DateTime: 2019-01-11 14:27
     * @param ChangeCardRequest $request
     * @return mixed
     * @throws \App\Exceptions\GeneralException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function changeCard(ChangeCardRequest $request)
    {

        $cardId = $request->get('card_id');
        $cardDetail = UserBankCard::find($cardId);
        if (!$cardDetail) {
            return failed('该银行卡不存在');
        }
        if ($cardDetail->uid != $this->user->id && $cardDetail->phone_num != $this->user->phone_num) {
            return failed('您无权请求该卡号数据', Response::HTTP_FORBIDDEN);
        }
        $summaryId = $request->get('summary_id');
        Log::debug('接受参数为card_id-summary_id:'.$cardId.'--'.$summaryId.'userid'.$this->user->id);

        //判断是否需要换放款卡
        //接下来要判断  是否 这个人 是提现失败的  失败需要换提现的卡

        $localid = LoanApply::where(['user_id'=>$this->user->id])->orderBy('id','desc')->first();//查询locaid 下面查询放款结果
        if (!empty($localid)){
            $result = MoneyPlatformRequestFacade::queryLoanResult($localid->loan_id);
            Log::debug('用户换提现卡操作user_id:'.$this->user->id.'回调为:'.json_encode($result,JSON_UNESCAPED_UNICODE));
            //return success([], [], '回调为:'.json_encode($result,JSON_UNESCAPED_UNICODE));
            if ($result['code'] === '01') {
                //判断是否data里面 transType 为03 的 transStatus == F

                foreach ($result['data']['transMoneyList'] as $item){
                    if ($item['transType'] == 03 && $item['transStatus'] == 'F'){
                        //提现失败
                        $res = UserChangeBankCardRecord::changeCard($cardDetail, 1,null);

                        Log::debug('提现未成功用户换卡操作:->user_id'.$this->user->id.'返回信息为:->'.json_encode($res,JSON_UNESCAPED_UNICODE));
                        if ($res['code'] === '01') {
                            if (UserGlobal::where('uid', $this->user->id)->where('global_status', UserGlobal::STATUS_LOAN_CHANGE_CARD)->value('uid')) {
                                UserGlobal::where('uid', $this->user->id)->update(['global_status'=> UserGlobal::STATUS_LOAN_MONEY_PROCESSING]);
                            }
                            return success([], [], '替换收款卡成功');
                        } else {
                            return failed('替换收款卡失败：' . $res['message']);
                        }
                    }
                }
            }
        }

        $res = UserChangeBankCardRecord::changeCard($cardDetail, $request->get('purpose'),$summaryId);

        if ($res['code'] === '01') {
            if (UserGlobal::where('uid', $this->user->id)->where('global_status', UserGlobal::STATUS_LOAN_CHANGE_CARD)->value('uid')) {
                UserGlobal::where('uid', $this->user->id)->update(['global_status'=> UserGlobal::STATUS_LOAN_MONEY_PROCESSING]);
            }
            return success([], [], '操作成功');
        } else {
            return failed('请求换卡失败：' . $res['message']);
        }
    }


    /**
     * Description: 解绑用户银行卡
     * Author: liuju
     * DateTime: 2019-01-02 17:45
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public  function unbindCard(Request $request)
    {
        $cardInfo = UserBankCard::where('uid', $this->user->id)->where('card_num', $request->get('card_num'))->first();
        if (empty($cardInfo)) {
            return respond([], '银行卡信息不存在', Response::HTTP_BAD_REQUEST);
        }
        //缺少协议号
        if (empty($cardInfo->hold_agreement_num)) {
            return respond([], '相关协议号不存在', Response::HTTP_BAD_REQUEST);
        }
        //验证协议号的有效性
        $res = CommonPlatformRequestFacade::checkHoldAgreement($cardInfo->hold_agreement_num);
        Log::debug('验证协议号的有效性' . json_encode($res,JSON_UNESCAPED_UNICODE).'uid=>'.$this->user->id);
        if ($res['code'] !== '01') {
            return respond([], '解绑失败：' . $res['message'], Response::HTTP_BAD_REQUEST);
        }
        //解绑银行卡
        $res = CommonPlatformRequestFacade::unbindCard($cardInfo->hold_agreement_num);
        Log::debug('解绑银行卡' . json_encode($res,JSON_UNESCAPED_UNICODE).'uid=>'.$this->user->id);
        if ($res['code'] !== '01') {
            return respond([], '解绑失败：' . $res['message'], Response::HTTP_BAD_REQUEST);
        }
        $cardInfo->delete();
        return respond([], '解绑成功');
    }


    /**
     * 银行卡列表
     * @return mixed
     * @author luwei
     * @date 2019-01-08 22:16
     */
    public function bankList()
    {
        $key = RedisKey::BANK_ICON_LIST;
        $data = Redis::get($key);
        $info = json_decode($data,true);
        if(!$info){
            $bankIconList = AdminBankIcon::cursor();
            $info = [];
            foreach ($bankIconList as $k => $v) {
                $info[] = [
                    'id' => $v->id,
                    'name' => $v->bank_name,
                    'icon_oss_url' => $v->icon_oss_url ? Storage::disk('oss')->signUrl($v->icon_oss_url,3600):'',
                ];
            }
            Redis::setex($key,3600,json_encode($info,JSON_UNESCAPED_UNICODE));
        }

        return success($info);
    }

}